package snafu.implementation.actions.walk;

import java.util.List;

import snafu.framework.actions.AbstractAction;
import snafu.framework.actions.Intention;
import snafu.framework.objects.WorldObject;
import snafu.framework.states.StateItself;
import snafu.framework.view.Access;
import snafu.framework.worlds.Position;
import snafu.framework.worlds.Tile;
import snafu.framework.worlds.WorldMap;
import snafu.implementation.states.literals.position.PositionLiteralItself;
import snafu.implementation.states.literals.surround.SurroundLiteral;

public class WalkAction extends AbstractAction {

	public WalkAction(List<WorldObject> targets, Intention<?> intention) {
		super(targets, intention);
	}

	@Override
	public void execute(WorldMap worldMap) {
		// get the only target and its position
		WorldObject target = targets.get(0);
		Position targetPosition = worldMap.getPosition(target);

		// remove surroundings of the agent
		for (SurroundLiteral literal : agent.getState().getLiterals(SurroundLiteral.class)) {
			worldMap.removeObject(literal.getValue());
		}
		
		// remove agent from current position and add it to the targets position
		worldMap.removeObject(agent);
		worldMap.addObject(targetPosition, agent);
		
		// add surroundings to the new position
		for (Tile tile : worldMap.getNeighborhood(targetPosition)) {
			for (SurroundLiteral literal : agent.getState().getLiterals(SurroundLiteral.class)) {
				tile.addObject(literal.getValue());
			}
		}
		
		// set the new position in the agents state
		StateItself state = (StateItself) agent.getState();
		state.setLiteral(new PositionLiteralItself(targetPosition, Access.PRIVATE));
	}

	@Override
	public String output() {
		return agent + " walks on " + targets.get(0);
	}

	@Override
	public boolean supportMultiTargets() {
		return false;
	}
}
